#include "RevolWidget.h"
#include "BRepPrimAPI_MakeRevol.hxx"
#include "BRepBuilderAPI_MakeFace.hxx"

RevolWidget::RevolWidget(modelSoft* myModelSoft, QWidget *parent)
	:myModelSoft(myModelSoft)
	,QWidget(parent)
	, ui(new Ui::RevolWidgetClass())
{
	ui->setupUi(this);
	ui->modifyButton->setEnabled(false);
	ui->confirmButton->setEnabled(false);
	myModelSoft->myView->getInteractorStyle()->setRevolOperation(true);
	revolFeature = new RevolFeature();
	revolFeature->setRevolId(myModelSoft->shapeTag++);
    revolFeature->setShapeId(revolFeature->getRevolId());
	revolFeature->setRevolType(0);
	typeTag = 0;
	isModified = false;
	createConnection();
}

RevolWidget::~RevolWidget()
{
	delete ui;
}

void RevolWidget::createConnection()
{
	connect(myModelSoft->currFaceSelector, &OccFaceSelector::sentRevolSubShape, this, &RevolWidget::receiveRevolSelectedShape);
	connect(myModelSoft->currVertexSelector, &OccVertexSelector::sentRevolSubShape, this, &RevolWidget::receiveRevolSelectedShape);
	connect(myModelSoft->currShapeSelector, &OccShapeSelector::sentRevolSubShape, this, &RevolWidget::receiveRevolSelectedShape);
	connect(myModelSoft->currEdgeSelector, &OccEdgeSelector::sentRevolSubShape, this, &RevolWidget::receiveRevolSelectedShape);
	connect(ui->modifyButton, &QPushButton::clicked, this, &RevolWidget::onClickModify);
	connect(ui->confirmButton, &QPushButton::clicked, this, &RevolWidget::onClickConfirm);
	connect(ui->cancelButton, &QPushButton::clicked, this, &RevolWidget::onClickCancel);
	connect(ui->selectButton, &QPushButton::clicked, this, &RevolWidget::onClickSelect);
	connect(ui->typeSelect, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RevolWidget::typeChange);
}

void RevolWidget::onClickModify()
{
	gp_Dir revolDir(ui->pxInput->text().toDouble(), ui->pyInput->text().toDouble(), ui->pzInput->text().toDouble());
	gp_Pnt revolLocation(ui->pxInput_2->text().toDouble(), ui->pyInput_2->text().toDouble(), ui->pzInput_2->text().toDouble());
	revolFeature->setRevolLocation(revolLocation);
	revolFeature->setRevolDir(revolDir);

	//判断旋转方向是否有效 以及是否被修改过
	if (!(IsNearlyZero(revolDir.X()) && IsNearlyZero(revolDir.Y()) && IsNearlyZero(revolDir.Z())) && !isModified) {
		gp_Ax1 axis(revolLocation, revolDir);
		const TopoDS_Shape& newShape = BRepPrimAPI_MakeRevol(selectShape, axis, false);
		resultPipeline = myModelSoft->CreatePipeline(newShape, revolFeature->getRevolId(), true);
		revolFeature->setResultId(resultPipeline->GetShapeID());
		myModelSoft->myView->getRenderWindow()->Render();
		isModified = true;
		ui->confirmButton->setEnabled(true);

		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,255,255)");
		myModelSoft->myView->getInteractorStyle()->clearCurrSelector();
	}
}

void RevolWidget::onClickConfirm()
{
	QStandardItem* item1 = new QStandardItem(QString("旋转体-%1").arg(revolFeature->getRevolId()));
	int row = myModelSoft->ui->model->rowCount();
	item1->setEditable(false);
	myModelSoft->ui->model->setItem(row, 0, item1);
	QStandardItem* item2 = new QStandardItem(QString("隐藏"));
	item2->setCheckable(true);
	myModelSoft->ui->model->setItem(row, 1, item2);
	myModelSoft->m_Features.insert(std::pair<Standard_Integer, RevolFeature*>(revolFeature->getRevolId(), revolFeature));

	confirmCreated = true;
	close();
}

void RevolWidget::onClickCancel()
{
	//myModelSoft->myView->getInteractorStyle()->getSelectedPipelines
	// 清除已选择的Actor
	myModelSoft->myView->getInteractorStyle()->clearCurrSelector();
	myModelSoft->myView->getInteractorStyle()->setRevolOperation(false);
	// 没有点确定，删除创建的Actor
	if (!confirmCreated)
	{

		if (!resultPipeline.IsNull())
		{
			myModelSoft->RemovePipelineFromRenderer(resultPipeline);
			myModelSoft->myView->getRenderWindow()->Render();
		}
	}

	close();
}

void RevolWidget::onClickSelect()
{
	if (typeTag == 0) {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Vertex);
		myModelSoft->changeSelector(SM_Vertex);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		revolFeature->setRevolType(0);
	}
	else if (typeTag == 1) {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Edge);
		myModelSoft->changeSelector(SM_Edge);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		revolFeature->setRevolType(1);
	}
	else {
		myModelSoft->myView->getInteractorStyle()->setSelectionMode(SM_Face);
		myModelSoft->changeSelector(SM_Face);
		myModelSoft->myView->getInteractorStyle()->setCurrSelector(myModelSoft->currSelector);
		revolFeature->setRevolType(2);
	}
}

void RevolWidget::onClickCancelSelect()
{
	// 已经修改不能取消选中
	if (!selectShape.IsNull() && !isModified)
	{
		myModelSoft->currSelector->deleteSelectedShape(selectShape);
		selectShape = TopoDS_Shape();
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,255,255)");
		ui->modifyButton->setEnabled(false);
		targetReceive = false;
	}
}

void RevolWidget::typeChange(int type)
{
	typeTag = type;
}

void RevolWidget::receiveRevolSelectedShape(const TopoDS_Shape& subShape, Handle(QIVtkSelectionPipeline) pipeline)
{
	if (!targetReceive) {
		auto iter = myModelSoft->m_Features.find(pipeline->GetShapeID());
		if (iter == myModelSoft->m_Features.end()) {
			return;
		}
		revolFeature->setTargetFeature(iter->second);
		selectShape = subShape;
		switch (typeTag) {
		case 0:
		{
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_VERTEX, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					revolFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		case 1:
		{
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_EDGE, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					revolFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		case 2:
		{
			//查找选择边在父对象的索引值
			//映射容器，用于存储 TopoDS_Shape 对象的索引映射
			TopTools_IndexedMapOfShape M;
			//遍历 S 中的所有边	将边的索引添加到 M 中
			TopExp::MapShapes(pipeline->getShape(), TopAbs_FACE, M);
			int count = M.Extent();
			while (count >= 0) {
				if (M.FindKey(count).IsEqual(subShape)) {
					revolFeature->setSubShapeIndex(count);
					break;
				}
				count--;
			}
			break;
		}
		}
		ui->modifyButton->setEnabled(true);
		ui->targetSelSubWidget->setStyleSheet("background-color:rgb(255,178,102)");
		targetReceive = true;
	}
}
